﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CamelCaseWordSplitter
{
    public static class CamelCaseWordSplitter
    {
        /// <summary>
        /// Breaks up a CamelCased string into the pieces that comprise it. Should be moved into a utility class, but since this is an exercise...
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static List<string> ParseIntoWords(string s)
        {
            if (s == null)
                throw new ArgumentNullException("Could not parse the camel cased input into individual words because the input is null");
            else if (s.Any(c => !char.IsLetter(c)))
                throw new ArgumentException(string.Format("Could not parse the camel cased input \"{0}\" into individual words because it contains characters that are not english letters.", s));

            List<string> words = new List<string>();

            int startMarker = 0;

            for (int i = 1; i < s.Length; i++)
            {
                //Detect the end of a word by a change in character case between the current character and the next
                //Lower case to upper case - the current character is the last character in the word
                //Upper case to lower case - the character previous to the current character is the last character in the word

                int endMarker = -1;
                if (i == s.Length - 1 || (char.IsLower(s[i]) && char.IsUpper(s[i + 1])))
                    endMarker = i;
                else if (char.IsUpper(s[i]) && char.IsLower(s[i + 1]))
                    endMarker = i - 1;

                if (endMarker != -1)
                {
                    words.Add(s.Substring(startMarker, endMarker - startMarker + 1));
                    startMarker = endMarker + 1;

                    //Due to the design of the checks for the end of a word this extra increment is required
                    i++;
                }
            }

            //Due to the extra increment it is possible for the last word to be missed, this if statement handles that case
            if (s.Length > 0 && startMarker < s.Length)
                words.Add(s.Substring(startMarker, s.Length - 1 - startMarker + 1));

            return words;
        }
    }
}
